import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:love_app/common/su.dart';
import 'package:love_app/common/su_dialog.dart';
import 'package:love_app/enum/login_status.dart';
import 'package:love_app/enum/responst_status.dart';
import 'package:love_app/model/response_model.dart';

// class SuDio {
//   Dio dio = Dio(); // 实例一个dio

//   /// 封装dio_post
//   Future postRequest(String path,
//       {Function successCallBack,
//       Map data,
//       Map headers,
//       int timeOut,
//       Options options}) async {
//     Options _options = options ?? Options(headers: headers, receiveTimeout: 5);

//     return await dio
//         .post(path, data: data ?? null, options: _options)
//         .then((response) {
//       if (successCallBack != null) {
//         successCallBack();
//       }
//       Su().suPrint(response.data, msg: 'post成功请求结果');
//       return response;
//     }).catchError((onError) {
//       Su().suPrint(onError, msg: 'post请求发生异常');
//       _dioError(onError);
//       return SuDioError.hasError;
//     });
//   }

//    /// 封装dio_get
//   Future getRequest(String path,
//       {Function successCallBack,
//       Map data,
//       Map headers,
//       int timeOut,
//       Options options}) async {
//     Options _options = options ?? Options(headers: headers, receiveTimeout: 5);

//     return await dio
//         .get(path, options: _options)
//         .then((response) {
//       if (successCallBack != null) {
//         successCallBack();
//       }
//       Su().suPrint(response.data, msg: 'get成功请求结果');
//       return response;
//     }).catchError((onError) {
//       Su().suPrint(onError, msg: 'get请求发生异常');
//       _dioError(onError);
//       return SuDioError.hasError;
//     });
//   }
 
//   /// 处理请求发生的异常
//   _dioError(DioError error) {
//     // 错误信息
//     Map errorMap = {
//       'statusCode': error.response.statusCode ?? '',
//       'param': error.request.data ?? '',
//       'method': error.request.method ?? '',
//       'message': error.message ?? '',
//       'errorData': error.response.data ?? '',
//       'path': error.request.path ?? '',
//     };

//     Su().suPrint(errorMap, msg: '网络请求错误');
//     SuDialog().showToast(error.message.toString());
//     // 弹出错误信息对话框
//     // SuDialog().errorDialog(context, errorMap.toString());
//   }
// }




// 第二版封装dio
class SuRequest{
  Dio _dio = Dio(); // 实例一个dio
  Function _successCallback; // 成功回调
  Function _errorCallbak; // 失败回调

  /*
   * 发送get请求
   * @path String 请求地址(完整地址)
   * @queryParam Map get请求参数
   * @headersMap Map 请求头
   * @timeOut int 请求超时
   * @successCallback Function 成功回调
   * @errorCallbak Function 错误回调
   * @options Options
   */
  Future getRequest(String path, {Map queryParams, int timeOut, Map headersMap, Options options, 
    Function successCallback, Function errorCallbak, })async{
    
    _successCallback = successCallback ?? null;
    _errorCallbak = errorCallbak ?? null;

    /// 请求头必须是Map<String, dynamic>类型
    Map<String, dynamic> _headers = headersMap == null ? null : _newMap(headersMap);
    Options _options = options ?? Options(
      headers:  _headers,/// 请求头
      sendTimeout: timeOut ?? 5000,  /// 请求超时
    );
    Map _param = queryParams == null ? null :_newMap(queryParams);
    return await _dio.get(path,
        queryParameters: _param,
        options: _options,
      ).then((value){
        _successFun();
        return value;
      }).catchError((error){
        _errorFun();
        _dioError(error);
        // return SuDioError.hasError;
      });
  }

  /*
   * 发送post请求
   * @path String 请求地址(完整地址)
   * @queryParam Map get请求参数
   * @data Map post请求参数
   * @headersMap Map 请求头
   * @timeOut int 请求超时
   * @successCallback Function 成功回调
   * @errorCallbak Function 错误回调
   * @options Options
   */
  Future postRequest(String path, {Map queryParams, Map data, int timeOut, Map headersMap, Options options, 
    Function successCallback, Function errorCallbak, })async{
    
    _successCallback = successCallback ?? null;
    _errorCallbak = errorCallbak ?? null;

    Options _options = options ?? Options(
      headers: headersMap == null ? null :_newMap(headersMap), /// 请求头
      sendTimeout: timeOut ?? 5000,  /// 请求超时
    );
    Map _param = queryParams == null ? null :_newMap(queryParams);

    return await _dio.post(path,
        data: data,
        queryParameters: _param,
        options: _options,
      ).then((value){
        // 没有发生异常
        _successFun();
        return value;
      }).catchError((error){
        // 发生异常
        _errorFun();
        _dioError(error); // 打印异常
        // return SuDioError.hasError;
      });
  }


  // 踩坑，暂时不知道为什么要转换
  Map<String, dynamic> _newMap(Map headers){
    return Map<String, dynamic>.from(headers);
  }

  // 如果success回调函数不为空，这调用
  void _successFun(){
    if(_successCallback != null){
      _successCallback();
    }
  }

  // 如果eror回调函数不为空，这调用
  void _errorFun(){
    SuDialog.showToast('请求异常');
    if(_successCallback != null){
      _errorCallbak();
    }
  }

   /// 处理请求发生的异常
  _dioError(DioError error) {
    // 错误信息
    Map errorMap = {
      'statusCode': error.response.statusCode ?? '',
      'param': error.request.data ?? '',
      'method': error.request.method ?? '',
      'message': error.message ?? '',
      'errorData': error.response.data ?? '',
      'path': error.request.path ?? '',
    };

    Su.suPrints(errorMap, msg: '网络请求错误');
    SuDialog.showToast(error.message.toString(), toastLength: Toast.LENGTH_LONG);
    // 弹出错误信息对话框
    // SuDialog().errorDialog(context, errorMap.toString());
  }
}

// 第三版request_dio

class SuDio extends _BaseDio{
  Dio _dio = Dio(); // 实例一个dio

  Function _successCallback; // 成功回调
  Function _unSuccessCallBack; // 没有成功回调
  Function _errorCallbak; // 异常回调
  
  /*
   * 发送get请求
   * @path String 请求地址(完整地址)
   * @queryParam Map get请求参数
   * @headersMap Map 请求头
   * @timeOut int 请求超时
   * @successCallback Function 成功回调
   * @unSuccessCallBack Function 失败回调
   * @errorCallbak Function 异常回调
   * @options Options
   */
  Future<ResponseModel> getRequest(String path, {Map queryParams, int timeOut, Map headersMap, Options options, 
    Function successCallback, Function errorCallbak, Function unSuccessCallBack})async{
    
    _successCallback = successCallback ?? null;
    _errorCallbak = errorCallbak ?? null;
    _unSuccessCallBack = unSuccessCallBack ?? null;

    /// 请求头必须是Map<String, dynamic>类型
    Map<String, dynamic> _headers = headersMap == null ? null : _newMap(headersMap);
    Options _options = options ?? Options(
      headers:  _headers,/// 请求头
      sendTimeout: timeOut ?? 5000,  /// 请求超时
    );
    Map _param = queryParams == null ? null :_newMap(queryParams);
    ResponseModel model = await _dio.get(path,
        queryParameters: _param,
        options: _options,
      ).then((response){
        ResponseModel model = _getResponseStatus(response);
        // 没有发生异常
        return model;
      }).catchError((error){
        // 发生异常
        _dioError(error); // 打印异常
        _errorFun();
      });
    return model;
  }

  /*
   * 发送post请求
   * @path String 请求地址(完整地址)
   * @queryParam Map get请求参数
   * @data Map post请求参数
   * @headersMap Map 请求头
   * @timeOut int 请求超时
   * @successCallback Function 成功回调
   * @unSuccessCallBack Function 失败回调
   * @errorCallbak Function 异常回调
   * @options Options
   */
  Future<ResponseModel> postRequest(String path, {Map queryParams, Map data, int timeOut, Map headersMap, Options options, 
    Function successCallback, Function errorCallbak, Function unSuccessCallBack})async{
    
    _successCallback = successCallback ?? null;
    _errorCallbak = errorCallbak ?? null;
    _unSuccessCallBack = unSuccessCallBack ?? null;

    Options _options = options ?? Options(
      headers: headersMap == null ? null :_newMap(headersMap), /// 请求头
      sendTimeout: timeOut ?? 5000,  /// 请求超时
    );
    Map _param = queryParams == null ? null :_newMap(queryParams);

    ResponseModel model = await _dio.post(path,
        data: data,
        queryParameters: _param,
        options: _options,
      ).then((response){
        ResponseModel model = _getResponseStatus(response);
        // 没有发生异常
        return model;
      }).catchError((error){
        // 发生异常
        _dioError(error); // 打印异常
        _errorFun();
        // return SuDioError.hasError;
      });
    return model;
  }

    /*
   * 发送FormData请求
   * @path String 请求地址(完整地址)
   * @queryParam Map get请求参数
   * @data Map post请求参数
   * @headersMap Map 请求头
   * @timeOut int 请求超时
   * @successCallback Function 成功回调
   * @unSuccessCallBack Function 失败回调
   * @errorCallbak Function 异常回调
   * @options Options
   */
  Future<ResponseModel> formDataRequest(String path, {Map formDataMap, int timeOut, Map headersMap, Options options, 
    Function successCallback, Function errorCallbak, Function unSuccessCallBack})async{
    
    _successCallback = successCallback ?? null;
    _errorCallbak = errorCallbak ?? null;
    _unSuccessCallBack = unSuccessCallBack ?? null;

    Options _options = options ?? Options(
      headers: headersMap == null ? null :_newMap(headersMap), /// 请求头
      sendTimeout: timeOut ?? 5000,  /// 请求超时
    );
    FormData formData = FormData.fromMap(_newMap(formDataMap));

    ResponseModel model = await _dio.post(path,
        data: formData,
        options: _options,
      ).then((response){
        ResponseModel model = _getResponseStatus(response);
        // 没有发生异常
        return model;
      }).catchError((error){
        // 发生异常
        _dioError(error); // 打印异常
        _errorFun();
        // return SuDioError.hasError;
      });
    return model;
  }
}


/// 封装dio基类
class _BaseDio{
  Function _successCallback; // 成功回调
  Function _unSuccessCallBack; // 没有成功回调
  Function _errorCallbak; // 异常回调


  // 返回请求是否成功
  ResponseModel _getResponseStatus(Response response){
    var data = response.data;
    if(data['code'] == 200){
      // 请求成功
      _successFun();
      return ResponseModel(
        response: response, data: data, status: ResponseStatusType.success, toJsonModel: data, loginStatus: LoginStatus.login 
      );
    }else if(data['code'] == 20001){
      // 登录状态已经失效
      return ResponseModel(
        response: response, data: data, status: ResponseStatusType.unSuccess, toJsonModel: data, loginStatus: LoginStatus.noLogin
      );
    }
    // 请求成功(登录状态没有失效 )
    _unSuccessFun(response);
    return ResponseModel(
        response: response, data: data['data'], status: ResponseStatusType.success, toJsonModel: data, loginStatus: LoginStatus.login 
      );
  }

  // 踩坑，暂时不知道为什么要转换
  Map<String, dynamic> _newMap(Map headers){
    return Map<String, dynamic>.from(headers);
  }

  // 如果success回调函数不为空，这调用
  void _successFun(){
    if(_successCallback != null){
      _successCallback();
    }
  }

  // 如果eror回调函数不为空，这调用
  void _errorFun(){
    SuDialog.showToast('请求异常');
    if(_successCallback != null){
      _errorCallbak();
    }
  }

  // 如过unSuccess回调函数不为空，则调用
  void _unSuccessFun(Response response){
    SuDialog.showToast(response.data['message']);
    if(_unSuccessCallBack != null){
      _unSuccessCallBack();
    }
  }

   /// 处理请求发生的异常
  _dioError(DioError error) {
    // 错误信息
    Map errorMap = {
      'statusCode': error.response.statusCode ?? '',
      'param': error.request.data ?? '',
      'method': error.request.method ?? '',
      'message': error.message ?? '',
      'errorData': error.response.data ?? '',
      'path': error.request.path ?? '',
    };

    Su().suPrint(errorMap, msg: '网络请求错误');
    SuDialog.showToast(error.message.toString(), toastLength: Toast.LENGTH_LONG);
    // 弹出错误信息对话框
    // SuDialog().errorDialog(context, errorMap.toString());
  }
}